package cn.buddha.jesw.mvc.controller;

import cn.buddha.jesw.mvc.service.MyService;
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName TongController
 * @Author 友野浩二
 * @Date 2019/12/4 20:16
 * @Description Spring MVC 【异步处理 方式二: @EnableAsync + @Async, 目前来看还是这种方式好】
 * @Version 1.0
 *
 * <pre>
 *     controller类不变；
 *     在service类上加@Async注解；
 *     启动类加@EnableAsync这个注解。
 * </pre>
 */
@RestController
@Slf4j
public class TongController {

    @Autowired
    private MyService myService;

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 测试异步任务没带返回值的，直接主线程瞬间就通过了
     * @Date 2019/12/4 22:47
     **/
    @RequestMapping(value = "/as", method = RequestMethod.GET)
    public String as() {
        log.info("cn.buddha.jesw.mvc.controller.TongController.as start...");
        Stopwatch stopwatch = Stopwatch.createStarted();// 创建自动start的计时器

        this.myService.task1();
        this.myService.task2();

        long timeConsuming = stopwatch.elapsed(TimeUnit.MILLISECONDS);
        log.info("耗时: {}ms", timeConsuming);
        return "总耗时: " + timeConsuming;
    }

    /**
     * @return java.lang.String
     * @Author 友野浩二
     * @Description // 测试异步任务带返回值的,【总耗时是最慢的那个任务的耗时】
     * @Date 2019/12/4 22:47
     **/
    @RequestMapping(value = "/ash", method = RequestMethod.GET)
    public String ash() throws ExecutionException, InterruptedException {
        log.info("cn.buddha.jesw.mvc.controller.TongController.ash start...");
        Stopwatch stopwatch = Stopwatch.createStarted();// 创建自动start的计时器

        // 异步任务,等待异步任务返回结果(使用异步回调,让每个被调用的方法返回一个Future类型的值)
        Future<String> task5Future = this.myService.task5();
        Future<String> task6Future = this.myService.task6();

        // isDone(): 用来判断异步任务是否执行完成。如果执行完成,则返回true; 如果未执行完成,则返回false
        while (!(task5Future.isDone() && task6Future.isDone())) {
            // 通过while循环来判断异步任务是否执行完成,等到所有异步任务都执行完成时,就自动结束while循环
        }

        // 取得异步任务的返回值并查看总耗时
        long timeConsuming = stopwatch.elapsed(TimeUnit.MILLISECONDS);

        System.out.println(task5Future.get() + ", " + task6Future.get());

        log.info("耗时: {}ms", timeConsuming);
        return "总耗时: " + timeConsuming;
    }

}
